package com.xingfly.service;

import com.xingfly.exception.TipException;
import com.xingfly.model.Event;
import com.xingfly.model.Post;
import com.xingfly.model.Tag;
import com.xingfly.model.User;
import com.xingfly.repository.PostRepository;
import com.xingfly.util.Type;
import com.xingfly.util.WebConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * post服务
 * Created by SuperS on 2016/12/12.
 */
@Service
public class PostService {

    public static final int POST_STATUS_PUB = 0;    //公开
    public static final int POST_STATUS_PRV = 1;    //私密
    public static final int POST_STATUS_SAVED = 2;    //保存
    public static final int POST_STATUS_EDIT = 3;    //编辑

    public static final int COMMENT_STATUS_ALLOWED = 0;        //允许评论
    public static final int COMMENT_STATUS_NOTALLOWED = 1;    //不允许评论

    public static final int POST_SUMMARY_LENGTH = 200;


    @Autowired
    private PostRepository postRepository;
    @Autowired
    private AccountService accountService;
    @Autowired
    private TagService tagService;
    @Autowired
    private EventService eventService;
    @Autowired
    private RelationService relationService;
    @Autowired
    private FeedService feedService;

    /**
     * 创建Post
     *
     * @param post      post对象
     * @param paramTags tag字符串
     */
    @Transactional
    public Post create(Post post, String paramTags) {
        Post returnPost = null;
        if (post.getAuthor() == null ||
                StringUtils.isEmpty(post.getTitle()) ||
                StringUtils.isEmpty(post.getContent())) {
            throw new TipException("Title Author Content 不能为空");
        }

        if (post.getPostStatus() == null) {
            post.setPostStatus(POST_STATUS_PUB);
        }
        if (post.getCommentStatus() == null) {
            post.setCommentStatus(COMMENT_STATUS_ALLOWED);
        }
        if (post.getPostStatus() < 0 || post.getPostStatus() > 3) {
            throw new TipException("Post状态异常");
        }
        if (post.getCommentStatus() != 0 && post.getCommentStatus() != 1) {
            throw new TipException("CommentStatus状态异常");
        }
        //第一种格式 通过 paramTags来创建映射关系
        if (!StringUtils.isEmpty(paramTags)) {
            //调用tagService 创建标签 已存在的直接返回到数组中。
            List<Tag> tags = tagService.create(tagService.toList(paramTags));
            post.setTags(tags);
            //保存post
            returnPost = postRepository.save(post);
            for (Tag tag : tags) {
                //创建post和tag的映射关系
                relationService.create(RelationService.RELATION_TYPE_POST, returnPost.getId(), tag.getId());
            }
        }
        //第二种 通过 json 转换成的tags数组创建映射关系
        if (post.getTags() != null) {
            List<Tag> tags = tagService.create(post.getTags());
            post.setTags(tags);
            returnPost = postRepository.save(post);
            for (Tag tag : tags) {
                relationService.create(RelationService.RELATION_TYPE_POST, returnPost.getId(), tag.getId());
            }
        }
        //如过简介为空 设置 截取Content内容作为简介
        if (StringUtils.isEmpty(post.getExcerpt())) {
            post.setExcerpt(getExcerpt(post.getContent()));
        }
        //如果没有tag直接保存
        returnPost = postRepository.save(post);
        return returnPost;
    }

    /**
     * 通过内容获取简介
     *
     * @param content 内容字符串
     */
    private String getExcerpt(String content) {
        int end = content.length();
        if (StringUtils.isEmpty(content)) {
            return null;
        }
        if (end > WebConstant.DEFAULT_POST_EXCERPT) {
            end = WebConstant.DEFAULT_POST_EXCERPT;
        }
        return content.substring(0, end) + "...";
    }

    /**
     * 创建Post
     *
     * @param post 创建Post
     */
    public Post create(Post post) {
        return create(post, null);
    }

    /**
     * 根据ID查询Post
     *
     * @param id postID
     */
    public Post findById(Long id) {
        return postRepository.findOne(id);
    }

    /**
     * 根据ID列表查询post列表
     *
     * @param ids id列表
     */
    public List<Post> findPostsByIds(List<Long> ids) {
        return postRepository.findByIds(ids);
    }

    /**
     * 根据用户ID获取Post列表
     */
    public List<Post> findPostsByUserId(Long userId, Integer page, Integer num) {
        return postRepository.findByAuthorId(userId, new PageRequest(page, num));
    }

    /**
     * 不分页获取Post列表
     */
    public List<Post> findPostsByUserId(Long userId) {
        return postRepository.findByAuthorId(userId);
    }

    /**
     * 查找某个用户的Post列表 按照近期排列
     *
     * @param userId 用户ID
     */
    public List<Post> findPostsByUserIdOrderByDesc(Long userId, Integer page, Integer num) {
        return postRepository.findByAuthorIdOrderByCreateTime(userId, new PageRequest(page, num));
    }

    /**
     * 根据postID查询作者
     *
     * @param postId postID
     */
    public User findAuthorByPostId(Long postId) {
        return postRepository.findAuthorByPostId(postId);
    }

    /**
     * 查询用户的post数量
     *
     * @param userId 用户ID
     */
    public Long count(Long userId) {
        return postRepository.findPostCountByAuthorId(userId);
    }

    /**
     * 删除Post
     *
     * @param postId postID
     */
    public void delete(Long postId) {
        postRepository.delete(postId);
        Event event = eventService.getEvent(Type.OBJECT_TYPE_POST, postId);
        if (event != null) {
            eventService.delete(Type.OBJECT_TYPE_POST, postId);
            feedService.delete(postRepository.findAuthorByPostId(postId).getId(), postId);
        }
    }

    /**
     * 不分页获取所有post
     */
    public List<Post> findAll() {
        return postRepository.findAll();
    }

    /**
     * 根据id获取post
     *
     * @
     */
    public Post findOne(Long id) {
        return postRepository.findOne(id);
    }

    /**
     * 分页获取post
     */
    public Page<Post> findAll(Pageable pageable) {
        return postRepository.findAll(pageable);
    }

}
